package ru.kreda.webapp.client.mvp;

import java.util.logging.Logger;

import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceChangeRequestEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.inject.Inject;

/**
 * Контроллер навигации приложения.
 * http://code.google.com/p/google-web-toolkit/issues/detail?id=6228
 */
public class AsyncPlaceController extends PlaceController {
	private static final Logger log = Logger.getLogger(AsyncPlaceController.class.getName());
	private final EventBus eventBus;
	private final Delegate delegate;
	private Place where = Place.NOWHERE;

	@Inject
	public AsyncPlaceController(EventBus eventBus) {
		super(eventBus, new Delegate() {

			@Override
			public boolean confirm(String message) {
				return false;
			}

			@Override
			public HandlerRegistration addWindowClosingHandler(ClosingHandler handler) {
				return null;
			}
		});
		this.eventBus = eventBus;
		this.delegate = new StyledDelegate(this);
	}

	@Override
	public Place getWhere() {
		return where;
	}

	@Override
	public void goTo(Place newPlace) {
		log.fine("идем в " + newPlace);
		if (getWhere().equals(newPlace)) {
			log.fine("игнорируем, это то же самое место " + newPlace);
			return;
		}
		PlaceChangeRequestEvent willChange = new PlaceChangeRequestEvent(newPlace);
		eventBus.fireEvent(willChange);
		String warning = willChange.getWarning();
		((StyledDelegate) delegate).setNewPlace(newPlace);
		if (warning == null || delegate.confirm(warning)) {
			goToForce(newPlace);
		}
	}

	private void goToForce(Place newPlace) {
		log.fine("идем (принудительно) в " + newPlace);
		where = newPlace;
		eventBus.fireEvent(new PlaceChangeEvent(newPlace));
	}

	public static class StyledDelegate implements Delegate {
		private final AsyncPlaceController placeController;
		private Place newPlace = null;

		public StyledDelegate(AsyncPlaceController placeController) {
			this.placeController = placeController;
		}

		public void setNewPlace(Place newPlace) {
			this.newPlace = newPlace;
		}

		@Override
		public HandlerRegistration addWindowClosingHandler(ClosingHandler handler) {
			return null;
		}

		@Override
		public boolean confirm(String message) {
			MessageBox.confirm("Подтверждение", message, new Listener<MessageBoxEvent>() {

				@Override
				public void handleEvent(MessageBoxEvent be) {
					if (Dialog.YES.equals(be.getButtonClicked().getItemId())) {
						placeController.goToForce(newPlace);
					}
				}

			});
			return false;
		}

	}

}
